﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace SimpleContainer
{
    #region CLASSES FOR SIMPLIFIED ACQUIRING

    #region public abstract class AcquireLock : IDisposable
    /// <summary>
    /// Base class for simplified acquiring.
    /// </summary>
    public abstract class AcquireLock : IDisposable
    {

        #region protected ReaderWriterLockSlim _Lock
        /// <summary>
        /// Wrapped read-write synchronization object.
        /// </summary>
        protected ReaderWriterLockSlim _Lock;
        #endregion

        #region protected bool _Disposed
        /// <summary>
        /// Indicates if this instance has been _Disposed.
        /// </summary>
        protected bool _Disposed = false;
        #endregion


        #region protected AcquireLock(ReaderWriterLockSlim rwLock)
        /// <summary>
        /// Initializes a new instance of AcquireLock class.
        /// </summary>
        /// <param name="rwLock">Wrapped read-write synchronization object to use.</param>
        protected AcquireLock(ReaderWriterLockSlim rwLock)
        {
            this._Lock = rwLock;
        }
        #endregion

        #region protected virtual void Dispose(bool disposing)
        /// <summary>
        /// Releases all resources.
        /// </summary>
        /// <param name="disposing">Value specifying if this method is called from Dispose method.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this._Disposed)
            {
                if (disposing)
                {
                    this.DoExitOperation();
                }
                this._Disposed = true;
            }
        }
        #endregion

        #region protected abstract void DoExitOperation()
        /// <summary>
        /// Executes exit operation.
        /// </summary>
        protected abstract void DoExitOperation();
        #endregion

        #region public void Dispose()
        /// <summary>
        /// Releases all resources.
        /// </summary>
        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }
        #endregion

        #region ~AcquireLock()
        /// <summary>
        /// Destructor.
        /// </summary>
        ~AcquireLock()
        {
            this.Dispose(false);
        }
        #endregion

    }
    #endregion

    #region public class AcquireWriteLock : IDisposable
    /// <summary>
    /// Class for simplified write-acquiring.
    /// </summary>
    public class AcquireWriteLock : AcquireLock
    {

        #region public AcquireWriteLock(ReaderWriterLockSlim rwLock)
        /// <summary>
        /// Initializes a new instance of AcquireWriteLock class.
        /// </summary>
        /// <param name="rwLock">Wrapped read-write synchronization object to use.</param>
        public AcquireWriteLock(ReaderWriterLockSlim rwLock)
            : base(rwLock)
        {
            this._Lock.EnterWriteLock();
        }
        #endregion

        #region protected override void DoExitOperation()
        /// <summary>
        /// Executes exit operation.
        /// </summary>
        protected override void DoExitOperation()
        {
            this._Lock.ExitWriteLock();
        }
        #endregion

    }
    #endregion

    #region public class AcquireReadLock : IDisposable
    /// <summary>
    /// Class for simplified read-acquiring.
    /// </summary>
    public class AcquireReadLock : AcquireLock
    {

        #region public AcquireReadLock(ReaderWriterLockSlim rwLock)
        /// <summary>
        /// Initializes a new instance of AcquireReadLock class.
        /// </summary>
        /// <param name="rwLock">Wrapped read-write synchronization object to use.</param>
        public AcquireReadLock(ReaderWriterLockSlim rwLock)
            : base(rwLock)
        {
            this._Lock.EnterReadLock();
        }
        #endregion

        #region protected override void DoExitOperation()
        /// <summary>
        /// Executes exit operation.
        /// </summary>
        protected override void DoExitOperation()
        {
            this._Lock.ExitReadLock();
        }
        #endregion

    }
    #endregion

    #region public class AcquireUpgradeableReadLock : IDisposable
    /// <summary>
    /// Class for simplified upgradeable read-acquiring.
    /// </summary>
    public class AcquireUpgradeableReadLock : AcquireLock
    {

        #region public AcquireUpgradeableReadLock(ReaderWriterLockSlim rwLock)
        /// <summary>
        /// Initializes a new instance of AcquireUpgradeableReadLock class.
        /// </summary>
        /// <param name="rwLock">Wrapped read-write synchronization object to use.</param>
        public AcquireUpgradeableReadLock(ReaderWriterLockSlim rwLock)
            : base(rwLock)
        {
            this._Lock.EnterUpgradeableReadLock();
        }
        #endregion

        #region protected override void DoExitOperation()
        /// <summary>
        /// Executes exit operation.
        /// </summary>
        protected override void DoExitOperation()
        {
            this._Lock.ExitUpgradeableReadLock();
        }
        #endregion

    }
    #endregion

    #endregion
}
